#include"list.h"
#include"stdio.h"

List::List()
{
    head.previous=head.next=0;
}
void List::initialize()
{
    head.previous=head.next=0;
}
int List::size()
{
    ListItem* temp=head.next;
    int counter=0;
    while(temp)
    {
        temp=temp->next;
        counter++;
    }
    return counter;
}
bool List::empty()
{
    return size()==0;
}
ListItem* List::back()
{
    ListItem* temp=head.next;
    if(!temp) return nullptr;
    while(temp->next)
    {
        temp=temp->next;
    }
    return temp;
}
void List::push_back(ListItem* item)
{
    ListItem* temp=back();
    if(!temp) temp= &head;
    temp->next=item;
    item->previous=temp;
    item->next=nullptr;
}
void List::pop_back()
{
    ListItem* temp=back();
    if(temp)
    {
        temp->previous->next=nullptr;
        temp->previous=temp->next=nullptr;
    }
}
ListItem* List::front()
{
    return head.next;
}
void List::push_front(ListItem* item)
{
    ListItem* temp=head.next;
    if(temp) temp->previous=item;
    item->previous=&head;
    item->next=temp;
    head.next=item;
}
void List::pop_front()
{
    ListItem* temp=head.next;
    if(temp)
    {
        if(temp->next) temp->next->previous=&head;
        head.next=temp->next;
        temp->previous=temp->next=nullptr;
    }
}
void List::insert(int pos,ListItem* item)
{
    if(pos==0)
    {
        push_front(item);
    }else if(pos<size()){
        ListItem* temp=at(pos);
        item->previous=temp->previous;
        item->next=temp;
        temp->previous->next=item;
        temp->previous=item;
    }else if(pos==size()){
        push_back(item);
    }
}
void List::insert_start(ListItem* item)
{
    ListItem* temp=head.next;
    int pos=0;
    while(temp && item->start > temp->start)
    {
        pos++;
        temp=temp->next;
    }
    insert(pos,item);
}
void List::erase(int pos)
{
    if(pos==0)
    {
        pop_front();
    }else if(pos<size()){
        ListItem* temp=at(pos);
        temp->previous->next=temp->next;
        if(temp->next) temp->next->previous=temp->previous;
        temp->previous=temp->next=nullptr;
    }
}
void List::erase(ListItem* item)
{
    ListItem* temp=head.next;
    while(temp && temp!=item) temp=temp->next;
    if(temp)
    {
        temp->previous->next=temp->next;
        if(temp->next) temp->next->previous=temp->previous;
        temp->previous=temp->next=nullptr;
    }
}
ListItem* List::at(int pos)
{
    if(pos<0 || pos>=size()) return nullptr;
    ListItem* temp=head.next;
    while(pos-- && temp)
    {
        temp=temp->next;
    }
    return temp;
}
int List::find(ListItem* item)
{
    int pos=0;
    ListItem* temp=head.next;
    while(temp && temp!=item)
    {
        temp=temp->next;
        pos++;
    }
    if(temp && temp==item) return pos;
    else return -1;
}
int List::find_start(int start)
{
    ListItem* temp=front();
    int pos=0;
    while(temp && temp->start!=start)
    {
        temp=temp->next;
        pos++;
    }
    if(temp && temp->start==start) return pos;
    else return -1;
}
void List::append_list(List add)
{
    if(add.empty())return;
    ListItem* temp=back();
    if(!temp)
    {
        head.next=add.head.next;
        add.head.next->previous=&head;
        add.head.next=nullptr;
    }else{
        temp->next=add.head.next;
        add.head.next->previous=temp;
        add.head.next=nullptr;
    }
}